package cn.udrm.water.base.v1.manager.service;

import java.util.List;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.udrm.water.base.v1.manager.cache.BaseRoleCache;
import cn.udrm.water.base.v1.manager.dto.BaseDepartmentDto;
import cn.udrm.water.base.v1.manager.dto.BaseDepartmentDtoMapper;
import cn.udrm.water.base.v1.manager.dto.BasePersonDto;
import cn.udrm.water.base.v1.manager.dto.BasePersonDtoMapper;
import cn.udrm.water.base.v1.manager.dto.BaseRoleDto;
import cn.udrm.water.base.v1.manager.dto.BaseRoleDtoMapper;
import cn.udrm.water.base.v1.manager.entities.BaseDepartment;
import cn.udrm.water.base.v1.manager.entities.BaseOrganization;
import cn.udrm.water.base.v1.manager.entities.BasePerson;
import cn.udrm.water.base.v1.manager.entities.BaseRole;
import cn.udrm.water.base.v1.manager.repository.BaseOrganizationRepository;
import cn.udrm.water.base.v1.manager.repository.BaseRoleRepository;

@Service
@Transactional(readOnly=true)
@CacheConfig(cacheNames="base_roles")
public class BaseRoleService {
	
	@Autowired
	private BaseRoleCache roleCache;
	@Autowired
	private BaseRoleRepository roleRepository;
	@Autowired
	private BaseRoleDtoMapper roleDtoMapper;
	@Autowired
	private BaseOrganizationRepository organizationRepository;
	@Autowired
	private BasePersonDtoMapper personDtoMapper;
	@Autowired
	private BaseDepartmentDtoMapper departmentDtoMapper;
	
	public List<BaseRoleDto> getAll() {
		List<BaseRole> findAll = roleRepository.findAll();
		if (findAll != null) {
			return roleDtoMapper.from(findAll);
		}
		return null;
	}
	
	@Cacheable(key="methodName+#p0")
	public BaseRoleDto getWithAllById(String id) {
		BaseRole findWithDepartmentsById = roleRepository.findWithDepartmentsById(id);
		BaseRole findWithPersonsById = roleRepository.findWithPersonsById(id);
		if (findWithDepartmentsById != null) {
			BaseRoleDto from = roleDtoMapper.from(findWithDepartmentsById);
			List<BaseDepartment> departments = findWithDepartmentsById.getDepartments();
			if (departments != null) {
				List<BaseDepartmentDto> deptList = departmentDtoMapper.from(departments);
				from.setDepartmentDtos(deptList);
			}
			List<BasePerson> persons = findWithPersonsById.getPersons();
			if (persons != null) {
				List<BasePersonDto> personList = personDtoMapper.from(persons);
				from.setPersonDtos(personList);
			}
			return from;
		}
		return null;
	}
	
	@Cacheable(key="methodName+#p0")
	public BaseRoleDto getWithPersons(String id) {
		BaseRole findWithPersonsById = roleRepository.findWithPersonsById(id);
		if (findWithPersonsById != null) {
			BaseRoleDto from = roleDtoMapper.from(findWithPersonsById);
			List<BasePerson> persons = findWithPersonsById.getPersons();
			if (persons != null) {
				List<BasePersonDto> from2 = personDtoMapper.from(persons);
				from.setPersonDtos(from2);
			}
			return from;
		}
		return null;
	}
	
	@Cacheable(key="methodName+#p0")
	public BaseRoleDto get(String id) {
		BaseRole baseRole = roleRepository.get(id);
		if (baseRole == null) {
			return null;
		}
		return roleDtoMapper.from(baseRole);
	}
	
	@Cacheable(key="methodName+#p0")
	public List<BaseRoleDto> findByOrganizationId(String organizationId) {
		List<BaseRole> findByOrganizationId = roleRepository.findByOrganizationId(organizationId);
		if (findByOrganizationId == null) {
			return null;
		}
		return roleDtoMapper.from(findByOrganizationId);
	}
	
	@Transactional(readOnly=false)
	public BaseRoleDto save(BaseRoleDto roleDto) {
		if (roleDto != null) {
			BaseRole baseRole = roleDtoMapper.to(roleDto);
			baseRole.setId(null);
			String organizationGuid = roleDto.getOrganizationGuid();
			BaseOrganization baseOrganization = null;
			if (StringUtils.isNotBlank(organizationGuid)) {
				Optional<BaseOrganization> findById = organizationRepository.findById(organizationGuid);
				baseOrganization = findById.get();
			}
			if (baseOrganization != null) {
				baseRole.setOrganization(baseOrganization);
			}
			BaseRole saveAndFlush = roleCache.saveAndFlush(baseRole);
			return roleDtoMapper.from(saveAndFlush);
		}
		return null;
	}
	
	@Transactional(readOnly=false)
	public BaseRoleDto update(BaseRoleDto roleDto) {
		if (roleDto != null) {
			BaseRole baseRole = roleDtoMapper.to(roleDto);
			String organizationGuid = roleDto.getOrganizationGuid();
			BaseOrganization baseOrganization = null;
			if (StringUtils.isNotBlank(organizationGuid)) {
				Optional<BaseOrganization> findById = organizationRepository.findById(organizationGuid);
				baseOrganization = findById.get();
			}
			if (baseOrganization != null) {
				baseRole.setOrganization(baseOrganization);
			}
			BaseRole saveAndFlush = roleCache.saveAndFlush(baseRole);
			return roleDtoMapper.from(saveAndFlush);
		}
		return null;
	}

}
